package org.shiro.service.Impl;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import org.apache.shiro.crypto.SecureRandomNumberGenerator;
import org.apache.shiro.crypto.hash.SimpleHash;
import org.shiro.bean.PageBean;
import org.shiro.dao.UserMapper;
import org.shiro.dao.UserRoleMapper;
import org.shiro.entity.User;
import org.shiro.entity.UserRole;
import org.shiro.service.UserService;
import org.shiro.util.FileUtils;
import org.shiro.util.PwdUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;
import org.springframework.web.multipart.MultipartFile;

import java.util.List;

/** @author HKC */
@Transactional(readOnly = true, propagation = Propagation.SUPPORTS)
@Service
public class UserServiceImpl implements UserService {
  @Autowired private UserMapper userMapper;
  @Autowired private UserRoleMapper userRoleMapper;

  @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
  @Override
  public User findUserByName(String username) {
    Assert.notNull(username, "参数错误");
    User user = userMapper.selectByName(username);
    if (user == null) {
      throw new NullPointerException("当前用户不存在");
    }
    return user;
  }

  @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
  @Override
  public int create(User user) {
    Assert.notNull(user, "参数错误");
    int res = userMapper.insertSelective(user);
    if (res == 0) {
      throw new IllegalArgumentException("添加新用户失败");
    }
    return res;
  }

  @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
  @Override
  public int remove(Long id) {
    User user = loadById(id);
    int res = userMapper.deleteByPrimaryKey(user.getId());
    if (res > 0) {
      List<UserRole> userRoleList = userRoleMapper.queryByUserId(id);
      if (userRoleList != null && userRoleList.size() > 0) {
        for (UserRole userRole : userRoleList) {
          //删除user-role中间表中的userId
          userRoleMapper.deleteByUserId(userRole.getUserid());
        }
      }
      return res;
    }
    return 0;
  }

  @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
  @Override
  public List<User> load(Long id) {
    User user = loadById(id);
    if (user == null) {
      throw new IllegalArgumentException("当前系统中没有该用户");
    }
    List<User> userList = userMapper.queryRoleByUserId(user.getId());
    if (userList == null || userList.size() <= 0) {
      throw new IllegalArgumentException("查询数据失败");
    }
    return userList;
  }

  @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
  @Override
  public User loadById(Long id) {
    Assert.notNull(id, "参数错误");
    User user = userMapper.selectByPrimaryKey(id);
    if (user == null) {
      throw new IllegalArgumentException("数据库中没有该用户，请先添加用户");
    }
    return user;
  }

  @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
  @Override
  public int modity(User user) {
    Assert.notNull(user, "参数错误");
    int res = userMapper.updateByPrimaryKeySelective(user);
    if (res > 0) {
      return res;
    }
    return 0;
  }

  @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
  @Override
  public List<User> selectByAll() {
    List<User> userList = userMapper.selectByAll();
    if (userList == null || userList.size() <= 0) {
      throw new IllegalArgumentException("查询所有数据失败");
    }
    return userList;
  }

  @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
  @Override
  public List<User> queryByLimit(int offset, int limit) {
    Assert.notNull(offset, "参数错误");
    Assert.notNull(limit, "参数错误");
    List<User> userList = userMapper.queryByLimit(offset, limit);
    if (userList == null || userList.size() <= 0) {
      throw new IllegalArgumentException("按照指定行数查询失败");
    }
    return userList;
  }

  @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
  @Override
  public List<User> selectRoleByUserId(Long userId) {
    Assert.notNull(userId, "参数错误");
    List<User> userList = userMapper.queryRoleByUserId(userId);
    if (userList.isEmpty() || userList.size() <= 0) {
      throw new IllegalArgumentException("当前没有数据");
    }
    return userList;
  }

  @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
  @Override
  public int changePassword(String username, String oldPassword, String newPassword) {
    Assert.notNull(username, "参数错误");
    Assert.notNull(oldPassword, "参数错误");
    Assert.notNull(newPassword, "参数错误");
    User user = findUserByName(username);
    if (user == null) {
      throw new IllegalArgumentException("用户不存在");
    }
    if (!user.getPassword().equals(PwdUtils.encryptPassword(oldPassword,user.getSalt()))) {
      throw new IllegalArgumentException("旧密码错误");
    }
    String salt = new SecureRandomNumberGenerator().nextBytes().toHex();
    user.setPassword(new SimpleHash("md5", newPassword, salt, 5).toHex());
    int res = userMapper.changePassword(user.getId(), user.getPassword(), salt);
    if (res == 0) {
      throw new IllegalArgumentException("更改用户口令失败");
    }
    return res;
  }

  @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
  @Override
  public List<User> selectByPage(PageBean pageBean) {
    Page<User> info = null;
    if (pageBean != null && pageBean.getRowsPerPage() > 0) {
      info = PageHelper.startPage(pageBean.getPageNum(), pageBean.getRowsPerPage());
    }
    List<User> userList = userMapper.selectByAll();
    if (info != null && userList != null && userList.size() > 0) {
      info = (Page<User>) userList;
      pageBean.setPageNum(info.getPageNum());
      pageBean.setMaxPage(info.getPages());
      pageBean.setRowsNum(info.getTotal());
    }
    return userList;
  }

  @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
  @Override
  public int changeImg(MultipartFile file, Long id) {
    Assert.notNull(file, "参数错误");
    User user = loadById(id);
    if (user.getUrl() == null) {
      throw new IllegalArgumentException("当前用户图像不存在");
    }
    FileUtils.removeFile(user.getUrl());
    user.setUrl(FileUtils.uploadFile(file).getAbsolutePath());
    int res = userMapper.changeImg(user.getUrl(), user.getId());
    if (res == 0) {
      throw new IllegalArgumentException("更改数据失败");
    }
    return res;
  }
}
